<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script>
  <script>
    /* setTimeout(() => {
      console.log('执行定时器回调')
    }, 1000);
    // 启动定时器之后执行一段时间超过延迟时间的任务
    for (let index = 0; index < 10000000; index++) {
      // 时间2s
    } */

    /* 
    ### promise的then()的理解
  - then()总是返回一个新的promise
  - 新promise的结果状态由then指定的回调函数执行的结果决定
    - 抛出错误
    - 返回失败的promise
    - 返回成功的promise
    - 返回其它任何值
    */

    /* new Promise((resolve, reject) => {
      // 前面可能需要执行一些异步操作

      // resolve(1)
      reject(2)
    }).then(
      value => {
        console.log('onResolved1', value)
      },
      reason => {
        console.log('onReejected1', reason)
        // 抛出错误 ==> 失败的promise
        // throw 3
        // 返回失败的promise
        // return Promise.reject(4)

        // 返回成功的promise
        // return Promise.resolve(5)
        // 其它所有/返回其它任意值
        return 6

      }
    ).then(
      value => {
        console.log('onResolved2', value)
      },
      reason => {
        console.log('onReejected2', reason)
      }
    ) */

    /* 
    
    ### Promise.all([promise1, promise2, promise3])
    - 问题: 
      - 如何在发送的多个请求成功后再显示数据?
      - 如何发3请求成功后再发4个请求?
    - 批量/一次性发送多个异步请求
    - 当都成功时, 返回的promise才成功
    - 一旦有一个失败的, 返回的promise就失败了
    */

   /*  function ajax(url) {
      return axios.get(url)
    }

    const p1 = ajax('url1')
    const p2 = ajax('url2')
    const p3 = ajax('url3')
    Promise.all([p1, p2, p3])
      .then(
        values => {
          console.log('显示所有成功的数据', values)
        },
        reason => {
          console.log('有个请求失败了', reason)
        }
      )
    Promise.all([p1, p2, p3])
    .then(
      values => {
        return ajax('url4')
      },
      reason => {
        console.log('有个请求失败了2', reason)
      }
    )
    .then(
      value => {
        console.log('第4个请求成功了', value)
      },
      reason => {
        console.log('第4个请求失败了', reason)
      }
    )
 */

    /* 
    async/await
    await: 结果为promise的表达式左侧
    async: await所在函数定义的左侧
    */
    function ajax(url) {
      return axios.get(url)
    }

    async function getData() {
      try {
        const response = await ajax('/1_js基础/product.json')   // 结果为promise的表达式左侧
        console.log('请求成功', response.data)
        return 1
      } catch (error) {
        alert(error.message)
        throw error
      }
      
    }

    function getData() {
      return new Promise((resolve, reject) => {
        ajax('/1_js基础/product.json')
          .then(
            response => {
              console.log('请求成功', response.data)
              resolve(1)
            },
            error => {
              alert(error.message)
              reject(error)
            }
          )
      })
    }

    async function test() {
      const result = await getData()  // async函数调用返回的promise的结果由async函数体执行结果决定
      console.log('result', result)
    }
    test()


  </script>
    
  <script>
    
    /* 
    .then()返回的promise的结果状态由什么决定?
      简单说: 由.then()指定并执行的回调函数的执行结果决定
      详细说: 
        什么情况导致promise是失败的?
          执行出错(抛异常了), 失败的reason就是抛出的错误
          返回一个失败的promise, 失败的reason就是返回的promise的reason
        什么情况导致promise是成功的?
          返回一个成功的promise, 成功的value就是返回promise的value
          返回一个非promise任务值, 也可以不返回(返回undefined), 成功的value就是返回值
    */

    // new Promise((resolve, reject) => {
    //   // resolve(1)
    //   reject(2)
    // }).then(
    //   value => {
    //     console.log('onResolved1', value)
    //   },   // onResolved
    //   reason => {
    //     console.log('onRejected1', reason)
    //     // 抛出错误
    //     // throw 3

    //     // 返回一个失败的promise
    //     // return Promise.reject(4)

    //     // 返回一个成功的promise
    //     // return Promise.resolve(5)

    //     // 返回其它任意值
    //     // return 6

    //     Promise.reject(4)

    //   } // onRejected
    // ).then(
    //   value => {
    //     console.log('onResolved2', value)
    //   },   
    //   reason => {
    //     console.log('onRejected2', reason)
    //   }
    // )



    /* 
    Promise.all()
    */
    // function ajax(url) {
    //   return axios.get(url)
    // }
    // const p1 = ajax(url1)
    // const p2 = ajax(url2)
    // const p3 = ajax(url3)
    // Promise.all([p1, p2, p3])
    //   .then(values => {
    //     return ajax(url4)
    //   })
    //   .then(value => {
    //     console.log(value) // 就是第4个请求成功的value
    //   })
    //   .catch(error => {

    //   })

    /* 
    1. 哪里用await: 一般在结果为promise的表达式左侧
        如果await 右侧表达式结果不是promise, 直接得到这个结果
    2. 如果用async: 离await最近的函数定义的左侧

    成功的value: await左侧以级下面的代码都是在成功之后执行(相当于在成功的回调中执行)
    失败的reason: 使用try...catch中在失败后执行(相当于在失败的回调中执行)

    调用async函数的得到是一个promise对象, promise的结果由aysnc函数体执行的结果决定(与.then类似)
     */

    /* function ajax(url) {
      return axios.get(url)
    }

    async function getProduct() {
      try {
        const response = await ajax('/1_js基础/product.json')
        return response.data
      } catch (error) {
        console.log('请求出错', error.message)
        // throw error
        return Promise.reject(error)
      }
    }

    // 等同于上面async&await的函数
    function getProduct() {
      return ajax('/1_js基础/product.json')
        .then(response => {
          return response.data
        })
        .catch(error => {
          console.log('请求出错', error.message)
          // throw error
          return Promise.reject(error)
        })
    }

    function test() {
      getProduct().then(value => {
        console.log(value)
      }).catch(error => {
        console.log('error', error.message)
      })
    }
    test() */

  </script>
</body>
</html>